public class JogoGuerra30Anos implements Jogo {

	public enum Situacao {
		AGUARDANDO_FORMULACAO, ENVIANDO_HIPOTESE, AGUARDANDO_REFUTACAO, HIPOTESE_NAO_REFUTADA, HIPOTESE_REFUTADA
	}

	private SequenciaJogadores ordemEntrada = new SequenciaJogadores();
	private SequenciaRefutadores ordemRefutacao;
	private Jogador jogadorCorrente;
	private ConjuntoInformacao armasDoJogo;
	private ConjuntoInformacao paisesDoJogo;
	private ConjuntoInformacao personagensDoJogo;
	private Situacao situacaoAtual;

	public JogoGuerra30Anos() {
		armasDoJogo = ConjuntoInformacao.obterConjuntoArmas();
		paisesDoJogo = ConjuntoInformacao.obterConjuntoPaises();
		personagensDoJogo = ConjuntoInformacao.obterConjuntoPersonagens();

		Jogador jogador1 = new Jogador("Jogador 1", PersonagemValor.RODOLFO);
		ConjuntoInformacao evidenciasJogador1 = new ConjuntoInformacao();
		evidenciasJogador1.adicionarInformacao(new Arma(ArmaValor.ARCABUZ.name()));
		jogador1.atribuirEvidencias(evidenciasJogador1);

		Jogador jogador2 = new Jogador("Jogador 2", PersonagemValor.RICHELIEU);
		ConjuntoInformacao evidenciasJogador2 = new ConjuntoInformacao();
		evidenciasJogador2.adicionarInformacao(new Pais(PaisValor.AUSTRIA.name()));
		jogador2.atribuirEvidencias(evidenciasJogador2);

		Jogador jogador3 = new Jogador("Jogador 3", PersonagemValor.TILLY);
		ConjuntoInformacao evidenciasJogador3 = new ConjuntoInformacao();
		evidenciasJogador3.adicionarInformacao(new Arma(ArmaValor.GANCHO.name()));
		jogador3.atribuirEvidencias(evidenciasJogador3);
		
		Jogador jogador4 = new Jogador("Jogador 4", PersonagemValor.AUVERGNE);
		ConjuntoInformacao evidenciasJogador4 = new ConjuntoInformacao();
		evidenciasJogador4.adicionarInformacao(new Personagem(PersonagemValor.RODOLFO.name()));
		jogador4.atribuirEvidencias(evidenciasJogador4);

		this.entrarNoJogo(jogador1);
		this.entrarNoJogo(jogador2);
		this.entrarNoJogo(jogador3);
		this.entrarNoJogo(jogador4);

		situacaoAtual = Situacao.AGUARDANDO_FORMULACAO;
	}

	@Override
	public void distribuirHipotese(Hipotese hip) {
		ordemRefutacao.distribuirHipotese(hip);
	}

	@Override
	public void formularHipotese(String armaString, String personagemString, String paisString) {
		Informacao arma = null;
		Informacao suspeito = null;
		Informacao pais = null;

		if (armasDoJogo.existeArma(armaString)) {
			arma = armasDoJogo.obterInformacao(armaString);
		}
		if (personagensDoJogo.existePersonagem(personagemString)) {
			suspeito = personagensDoJogo.obterInformacao(personagemString);
		}
		if (paisesDoJogo.existePais(paisString)) {
			pais = paisesDoJogo.obterInformacao(paisString);
		}

		jogadorCorrente.criarHipotese(arma, suspeito, pais);

		situacaoAtual = Situacao.ENVIANDO_HIPOTESE;

	}

	@Override
	public ConjuntoInformacao obterArmasDisponiveis() {
		if (armasDoJogo == null) {
			armasDoJogo = ConjuntoInformacao.obterConjuntoArmas();
		}
		return armasDoJogo;
	}

	@Override
	public ConjuntoInformacao obterPaisesDisponiveis() {
		ConjuntoInformacao paisesDisponiveis = new ConjuntoInformacao();
		paisesDisponiveis.adicionarInformacao(jogadorCorrente.obterRegiaoAtual());
		return paisesDisponiveis;
	}

	@Override
	public ConjuntoInformacao obterPersonagensDisponiveis() {
		if (personagensDoJogo == null) {
			personagensDoJogo = ConjuntoInformacao.obterConjuntoPersonagens();
		}
		return personagensDoJogo;
	}

	public void entrarNoJogo(Jogador jogador) {
		ordemEntrada.entrarNoJogo(jogador);
		if (jogadorCorrente == null) {
			jogadorCorrente = jogador;
		}
	}

	public void determinarRefutadores() {
		ordemRefutacao = ordemEntrada.obterRefutadores(jogadorCorrente);
	}

	@Override
	public Situacao obterSituacao() {
		return situacaoAtual;
	}

	@Override
	public Hipotese obterHipotese() {
		return jogadorCorrente.obterHipotese();
	}

	@Override
	public void aplicarRefutacao(Informacao evidencia) {
		jogadorCorrente.aplicarRefutacao(evidencia);
	}

	@Override
	public boolean existeRefutador() {
		return ordemRefutacao.existeRefutador();
	}

	@Override
	public boolean hipoteseRefutada() {
		return jogadorCorrente.hipoteseRefutada();
	}

	@Override
	public Hipotese obterHipoteseCorrente() {
		return jogadorCorrente.obterHipotese();
	}

	@Override
	public ConjuntoInformacao obterEvidenciasParaRefutacao() {
		return obterRefutadorDaVez().obterEvidenciasParaRefutacao();
	}

	@Override
	public Jogador obterRefutadorDaVez() {
		return ordemRefutacao.obterRefutadorDaVez();
	}

	@Override
	public Jogador obterJogadorCorrente() {
		return jogadorCorrente;
	}

}
